Completed
Pull Request — master (#227)
by Sander
03:18
created

angular.controller(ꞌCredentialCtrlꞌ)   C

Complexity

Conditions 8
Paths 32

Size

Total Lines 401

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
nc 32
nop 19
dl 0
loc 401
rs 5.2676
c 1
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
/**
2
 * Nextcloud - passman
3
 *
4
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
5
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
(function () {
24
	'use strict';
25
26
27
	/**
28
	 * @ngdoc function
29
	 * @name passmanApp.controller:MainCtrl
30
	 * @description
31
	 * # MainCtrl
32
	 * Controller of the passmanApp
33
	 */
34
	angular.module('passmanApp')
35
		.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
36
			'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService', 'CacheService', 'ShareService', 'SharingACL', '$interval', '$filter', '$routeParams', '$sce', '$translate',
37
			function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService, CacheService, ShareService, SharingACL, $interval, $filter, $routeParams, $sce, $translate) {
38
				$scope.active_vault = VaultService.getActiveVault();
39
				if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
40
					if (!$scope.active_vault) {
41
						$location.path('/');
42
					}
43
				} else {
44
					if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
45
						var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
46
						_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
47
						VaultService.setActiveVault(_vault);
48
						$scope.active_vault = _vault;
49
						//@TODO check if vault exists
50
					}
51
				}
52
53
				$scope.show_spinner = true;
54
				var fetchCredentials = function () {
55
					VaultService.getVault({guid: $routeParams.vault_id}).then(function (vault) {
56
						var vaultKey = angular.copy($scope.active_vault.vaultKey);
57
						var _credentials = angular.copy(vault.credentials);
58
						vault.credentials = [];
59
						$scope.active_vault = vault;
60
						$scope.active_vault.vaultKey = vaultKey;
61
						VaultService.setActiveVault($scope.active_vault);
62
						for (var i = 0; i < _credentials.length; i++) {
63
							var _credential = _credentials[i];
64
							try {
65
								if (!_credential.shared_key) {
66
									_credential = CredentialService.decryptCredential(angular.copy(_credential));
67
68
								} else {
69
									var enc_key = EncryptService.decryptString(_credential.shared_key);
70
									_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
71
								}
72
								_credential.tags_raw = _credential.tags;
73
							} catch (e) {
74
75
								NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
76
								//$rootScope.$broadcast('logout');
77
								//SettingsService.setSetting('defaultVaultPass', null);
78
								//.setSetting('defaultVault', null);
79
								//$location.path('/')
80
81
							}
82
							if (_credential.tags) {
83
								TagService.addTags(_credential.tags);
84
							}
85
							_credentials[i] = _credential;
86
						}
87
88
						ShareService.getCredendialsSharedWithUs(vault.guid).then(function (shared_credentials) {
89
							for (var c = 0; c < shared_credentials.length; c++) {
90
								var _shared_credential = shared_credentials[c];
91
								var decrypted_key = EncryptService.decryptString(_shared_credential.shared_key);
92
								var _shared_credential_data;
93
								try {
94
									_shared_credential_data = ShareService.decryptSharedCredential(_shared_credential.credential_data, decrypted_key);
95
								} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
96
97
								}
98
								if (_shared_credential_data) {
99
									delete _shared_credential.credential_data;
100
									_shared_credential_data.acl = _shared_credential;
101
									_shared_credential_data.acl.permissions = new SharingACL(_shared_credential_data.acl.permissions);
102
									_shared_credential_data.tags_raw = _shared_credential_data.tags;
103
									if (_shared_credential_data.tags) {
104
										TagService.addTags(_shared_credential_data.tags);
105
									}
106
									_credentials.push(_shared_credential_data);
107
								}
108
							}
109
							angular.merge($scope.active_vault.credentials, _credentials);
110
							$scope.show_spinner = false;
111
						});
112
					});
113
				};
114
115
				var getPendingShareRequests = function () {
116
					ShareService.getPendingRequests().then(function (shareRequests) {
117
						if (shareRequests.length > 0) {
118
							$scope.incoming_share_requests = shareRequests;
119
							jQuery('.share_popup').dialog({
120
								width: 600,
121
								position: ['center', 90]
122
							});
123
						}
124
					});
125
				};
126
127
128
				var refresh_data_interval = null;
129
				if ($scope.active_vault) {
130
					$scope.$parent.selectedVault = true;
131
					fetchCredentials();
132
					getPendingShareRequests();
133
					refresh_data_interval = $interval(function () {
134
						fetchCredentials();
135
						getPendingShareRequests();
136
					}, 60000 * 5);
137
				}
138
				$scope.$on('$destroy', function () {
139
					$interval.cancel(refresh_data_interval);
140
				});
141
142
143
				$scope.permissions = new SharingACL(0);
144
145
				$scope.hasPermission = function (acl, permission) {
146
					if (acl) {
147
						var tmp = new SharingACL(acl.permission);
148
						return tmp.hasPermission(permission);
149
					} else {
150
						return true;
151
					}
152
153
				};
154
155
				$scope.acceptShareRequest = function (share_request) {
156
					var crypted_shared_key = share_request.shared_key;
157
					var private_key = EncryptService.decryptString(VaultService.getActiveVault().private_sharing_key);
158
159
					private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
160
					/** global: forge */
161
					crypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
162
					crypted_shared_key = EncryptService.encryptString(crypted_shared_key);
163
164
					ShareService.saveSharingRequest(share_request, crypted_shared_key).then(function () {
165
						var idx = $scope.incoming_share_requests.indexOf(share_request);
166
						$scope.incoming_share_requests.splice(idx, 1);
167
						var active_share_requests = false;
168
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
169
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
170
								active_share_requests = true;
171
							}
172
						}
173
						if (active_share_requests === false) {
174
							jQuery('.ui-dialog').remove();
175
							fetchCredentials();
176
						}
177
					});
178
				};
179
180
				$scope.declineShareRequest = function (share_request) {
181
					ShareService.declineSharingRequest(share_request).then(function () {
182
						var idx = $scope.incoming_share_requests.indexOf(share_request);
183
						$scope.incoming_share_requests.splice(idx, 1);
184
						var active_share_requests = false;
185
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
186
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
187
								active_share_requests = true;
188
							}
189
						}
190
						if (active_share_requests === false) {
191
							jQuery('.ui-dialog').remove();
192
							fetchCredentials();
193
						}
194
					});
195
				};
196
197
198
199
				var settingsLoaded = function () {
200
					$scope.settings = SettingsService.getSettings();
201
				};
202
203
				if(!SettingsService.getSetting('settings_loaded')){
204
					$rootScope.$on('settings_loaded', function () {
205
						settingsLoaded();
206
					});
207
				} else {
208
					settingsLoaded();
209
				}
210
211
212
				$scope.addCredential = function () {
213
					var new_credential = CredentialService.newCredential();
214
					var enc_c = CredentialService.encryptCredential(new_credential);
215
					SettingsService.setSetting('edit_credential', enc_c);
216
					$location.path('/vault/' + $scope.active_vault.guid + '/new');
217
				};
218
219
				$scope.editCredential = function (credential) {
220
					var _credential = angular.copy(credential);
221
					$rootScope.$emit('app_menu', false);
222
					SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
223
					$location.path('/vault/' + $scope.active_vault.guid + '/edit/' + _credential.guid);
224
				};
225
226
				$scope.getRevisions = function (credential) {
227
					var _credential = angular.copy(credential);
228
					$rootScope.$emit('app_menu', false);
229
					SettingsService.setSetting('revision_credential', CredentialService.encryptCredential(_credential));
230
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/revisions');
231
				};
232
233
				$scope.shareCredential = function (credential) {
234
					var _credential = angular.copy(credential);
235
					$rootScope.$emit('app_menu', false);
236
					SettingsService.setSetting('share_credential', CredentialService.encryptCredential(_credential));
237
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/share');
238
				};
239
240
				var notification;
241
				$scope.deleteCredential = function (credential) {
242
					var _credential = angular.copy(credential);
243
					try {
244
						_credential = CredentialService.decryptCredential(angular.copy(credential));
245
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
246
247
					}
248
					_credential.delete_time = new Date().getTime() / 1000;
249
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
250
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
251
							$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
252
						}
253
					}
254
					$scope.closeSelected();
255
					if (notification) {
256
						NotificationService.hideNotification(notification);
257
					}
258
					notification = NotificationService.showNotification($translate.instant('credential.deleted'), 5000,
259
						function () {
260
							CredentialService.updateCredential(_credential).then(function (result) {
261
								if (result.delete_time > 0) {
262
									notification = false;
263
264
								}
265
							});
266
						});
267
268
				};
269
270
				$scope.recoverCredential = function (credential) {
271
					var _credential = angular.copy(credential);
272
					try {
273
						_credential = CredentialService.decryptCredential(angular.copy(credential));
274
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
275
276
					}
277
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
278
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
279
							$scope.active_vault.credentials[i].delete_time = 0;
280
						}
281
					}
282
					_credential.delete_time = 0;
283
					$scope.closeSelected();
284
					if (notification) {
285
						NotificationService.hideNotification(notification);
286
					}
287
					NotificationService.showNotification($translate.instant('credential.recovered'), 5000,
288
						function () {
289
							CredentialService.updateCredential(_credential).then(function () {
290
								notification = false;
291
292
							});
293
						});
294
295
				};
296
297
				$scope.destroyCredential = function (credential) {
298
					var _credential = angular.copy(credential);
299
					CredentialService.destroyCredential(_credential.guid).then(function () {
300
						for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
301
							if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
302
								$scope.active_vault.credentials.splice(i, 1);
303
								NotificationService.showNotification($translate.instant('credential.destroyed'), 5000);
304
								break;
305
							}
306
						}
307
					});
308
				};
309
310
				$scope.view_mode = 'list'; //@TODO make this a setting
311
				$scope.switchViewMode = function (viewMode) {
312
					$scope.view_mode = viewMode;
313
				};
314
315
				$scope.filterOptions = {
316
					filterText: '',
317
					fields: ['label', 'username', 'email', 'custom_fields']
318
				};
319
320
321
				$scope.filtered_credentials = [];
322
				$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function () {
323
					if (!$scope.active_vault) {
324
						return;
325
					}
326
					if ($scope.active_vault.credentials) {
327
						var credentials = angular.copy($scope.active_vault.credentials);
328
						var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
329
						filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
330
						filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
331
						$scope.filtered_credentials = filtered_credentials;
332
					}
333
				}, true);
334
335
				$scope.selectedtags = [];
336
				var to;
337
				$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
338
					var _selectedTags = [];
339
					for (var x = 0; x < _sTags.length; x++) {
340
						_selectedTags.push(_sTags[x].text);
341
					}
342
					$scope.selectedtags = _selectedTags;
343
					$timeout.cancel(to);
344
					if (_selectedTags.length > 0) {
345
						to = $timeout(function () {
346
							if ($scope.filtered_credentials) {
347
								var _filtered_tags = [];
348
								for (var i = 0; i < $scope.filtered_credentials.length; i++) {
349
									var tags = $scope.filtered_credentials[i].tags_raw;
350
									for (var x = 0; x < tags.length; x++) {
351
										var tag = tags[x].text;
352
										if (_filtered_tags.indexOf(tag) === -1) {
353
											_filtered_tags.push(tag);
354
										}
355
									}
356
								}
357
358
								$rootScope.$emit('limit_tags_in_list', _filtered_tags);
359
							}
360
						}, 50);
361
					}
362
				});
363
364
				$scope.delete_time = 0;
365
				$scope.showCredentialRow = function (credential) {
366
					if ($scope.delete_time === 0) {
367
						return credential.delete_time === 0;
368
					} else {
369
						return credential.delete_time > $scope.delete_time;
370
					}
371
372
				};
373
374
				$rootScope.$on('set_delete_time', function (event, time) {
375
					$scope.delete_time = time;
376
				});
377
378
				$scope.setDeleteTime = function (delete_time) {
379
					$scope.delete_time = delete_time;
380
				};
381
382
				$scope.selectedCredential = false;
383
				$scope.selectCredential = function (credential) {
384
					if(credential.description) {
385
						credential.description_html = $sce.trustAsHtml(angular.copy(credential.description).replace("\n", '<br />'));
386
					}
387
					$scope.selectedCredential = angular.copy(credential);
388
					$rootScope.$emit('app_menu', true);
389
				};
390
391
				$scope.closeSelected = function () {
392
					$rootScope.$emit('app_menu', false);
393
					$scope.selectedCredential = false;
394
				};
395
396
				$rootScope.$on('logout', function () {
397
					$scope.active_vault = null;
398
					$scope.credentials = [];
399
//				$scope.$parent.selectedVault = false;
400
401
				});
402
403
				$scope.clearState = function () {
404
					$scope.delete_time = 0;
405
				};
406
407
				$scope.downloadFile = function (credential, file) {
408
					var callback = function (result) {
409
						var key = null;
410
						if (!result.hasOwnProperty('file_data')) {
411
							NotificationService.showNotification($translate.instant('error.loading.file.perm'), 5000);
412
							return;
413
414
						}
415
						if (!credential.hasOwnProperty('acl') && credential.hasOwnProperty('shared_key')) {
416
							if (credential.shared_key) {
417
								key = EncryptService.decryptString(angular.copy(credential.shared_key));
418
							}
419
						}
420
						if (credential.hasOwnProperty('acl')) {
421
							key = EncryptService.decryptString(angular.copy(credential.acl.shared_key));
422
						}
423
424
						var file_data = EncryptService.decryptString(result.file_data, key);
425
						download(file_data, escapeHTML(file.filename), file.mimetype);
426
427
					};
428
429
					if (!credential.hasOwnProperty('acl')) {
430
						FileService.getFile(file).then(callback);
431
					} else {
432
						ShareService.downloadSharedFile(credential, file).then(callback);
433
					}
434
435
				};
436
437
			}]);
438
}());